local M = {}

local is_loaded = false

local function edit(line, file)
    cmd = "edit " .. file .. " | " .. line
    -- print("cmd=" .. cmd)
    vim.cmd(cmd)
end

local function load_database()
    local failed_string = "global: GTAGS not found"
    -- find `GTAGS` path
    local res = vim.fn.systemlist('global -pd')[1]
    if not res:find(failed_string) then
        vim.env.GTAGSROOT = res
        -- is_loaded = true
        is_loaded = true
    end
    return is_loaded
end


-- (code)
-- 1: find definations
-- 2: find referencies
function M.gtags_find_cword(code)
    if is_loaded == false and load_database() == false then
        print("Gtags Not Found.")
        return
    end

    local cword = vim.fn.expand("<cword>")

    -- set `global` command params by code.
    local cmd
    if code == 1 then
        cmd = "global -x " .. cword
    elseif code == 2 then
        cmd = "global -xr " .. cword
    end

    -- run `global` command
    local res = vim.fn.systemlist(cmd)
    if #res <= 0 then
        print("Not Found: " .. cword)
        return
    end

    -- check search result
    local index = 0
    if #res == 1 then
        index = 1
    else
        -- show list
        -- usage: nvim_echo({{"string1", "style1"}, {"string2", "style2"}}, wrap:bool, {underline = true, italic = true})
        vim.api.nvim_echo({{" Gtags found: " .. #res .. " " .. cword, "Title"}}, false, {})
        for index, row in ipairs(res) do
            -- print(" " .. index .. " " .. row)
            line, file, content = string.match(row, "%s*(%d+)%s*(%S+%.%S+)%s*(.+)$")
            vim.api.nvim_echo(
            {
                {" " .. index, "Number"},
                {"  " .. file .. ":" .. line, "String"},
                {"  " .. content, "Normal"},
            }, false, {})
        end

        -- user input
        -- vim.api.nvim_echo({{"Type number and <Enter>", "Title"}}, false, {})
        local success, input = pcall(vim.fn.input, " Type number: ")
        if success == false then
            return
        end
        --index = tonumber(vim.fn.input("-> "))
        index = tonumber(input)
        if not index or index > #res then -- user input is not a num-str
            return
        end
    end
    -- from `global` cmd result, get line-number and file-path
    line, file = string.match(res[index], "%s+(%d+)%s+([^%s]+)")
    edit(line, file)
end

function M.setup()
    local vimapi = vim.api
    vimapi.nvim_create_user_command("GtagsFindDefs", function() M.gtags_find_cword(1) end, {})
    vimapi.nvim_create_user_command("GtagsFindRefs", function() M.gtags_find_cword(2) end, {})
end

return M
